The present invention relates to computer systems and more particularly to memory management techniques.
A dynamic run-time environment for a language such as JAVA(trademark) is responsible for managing memory for objects that are created and destroyed during the execution of a program. An object is an entity that encapsulates data and, in some languages, operations associated with the object. Since the encapsulated data is stored in memory, objects are associated with particular regions of memory that are allocated and deallocated by the dynamic run-time environment.
The state of a program, or xe2x80x9cprogram state,xe2x80x9d is the set of the objects and the references between the objects that exist at a specific point in time during the execution of the program. A xe2x80x9creferencexe2x80x9d is used by a run-time environment to identify and ultimately access the region of memory for storing the data of the object. Typically, references between objects in a run-time environment are encoded using machine pointers. A machine pointer is an instance of a native type that contains the address of the object in the main memory, which can be a real memory address or, more commonly, a virtual address on a machine that implements a virtual memory system. Since machine pointers are closely coupled to the underlying hardware and firmware of a computer system, machine pointers have high performance and, hence, are a popular implementation for references.
In a run-time environment, however, managing the program state with machine-specific references such as machine pointers is sometimes disadvantageous. For example, it may be desirable to store the program state on disk or another secondary storage medium and restore the stored program state to main memory. Some run-time environments, in fact, are designed to use the same program state on different types of machines. For instance, such run-time environments provide load-balancing and crash recovery functions by transferring the execution of a program from one machine to another.
Lately, there has been much interest in using JAVA in a multi-user environment that allows multiple users to connect in separate, concurrent sessions to a server system, such as a relational database system. When designing a run-time environment for such a multi-user environment, scalability in terms of the number of simultaneous users who can establish separate sessions is very important. A significant constraint for user scalability is the size of the memory footprint that each session consumes. For example, a server system may have 100 Mb of memory for supporting all the user sessions. If the session memory footprint is 1 Mb, then only 100 users can be supported at one time. Therefore, it is desirable to reduce the session memory footprint to improve scalability.
One approach for reducing the session memory footprint is to provide a shorter duration memory named xe2x80x9ccall memoryxe2x80x9d that is active for the duration of a xe2x80x9ccallxe2x80x9d but automatically deallocated when the call terminates. A call is the period of time, when the user is actively using the server, such as processing a SQL statement in a database server. Accordingly, those objects that do not need to live beyond the duration of the call are placed in the call memory rather than session memory. When the call is completed, objects in the call memory are deallocated and the call-duration memory is reclaimed for use. This approach has been implemented in Oracle Corporation""s PL/SQL language, for instance, in which objects are explicitly declared as having the duration of a call or of a session. Memory management in such a language is straightforward because the objects are simply allocated in the memory that corresponds to their duration.
JAVA, however, defines the lifetime of many objects, especially system objects, to extend throughout the duration of a session and does not have the notion of a call or call memory. Accordingly, one approach is to simply ignore the provision of the call memory by the multi-user system and allocate every object in session memory, but this approach suffers from scalability because short-lived objects are unnecessarily allocated in session memory. Another approach is to allocate objects first in the shorter-duration call memory, and then, at the time the call terminates, migrate the live objects into the longer duration session memory. Dead objects, i.e. those objects that are no longer needed, are not migrated but are freed when the call memory is deallocated.
In this other approach, session memory is only consumed for the call memory objects that are still alive at the end of the call. Call memory objects are alive if a live object in session memory directly or indirectly refers to the call memory object. One way to identify such live call memory objects is to scan every line object in session memory, but there is a need for a more efficient method identifying call memory objects.
In addition, parallel processing and load balancing are useful techniques for improving performing in a multi-user environment. Parallel processing employs a plurality of computer processors for handling many calls at the same time, and load balancing ensures that idle processors are schedule to perform calls as the calls are made. In fact, the computer processors need not be identical but can be a networked collection of incompatible computers that are capable of accessing the same memory. Thus, it is possible in this environment for one processor to handle a call in a user session, and then another processor to handle the next call in the user session. Accordingly, it is desirable for the session state to be as machine-independent as possible. Call memory, on the other hand, does not need to be machine-independent because a call is typically serviced by only one of the processors at a time.
Differences between computer architectures, however, make machine-independence very difficult to achieve. For example, the size of a machine pointer is dictated by the architecture of the computer system. While many computer systems today employ 32-bit machine pointers, older microprocessors typically used 16-bit machine pointers and the latest computer processors are adopting 64-bit pointers. On some 64-bit machines, such as a Cray(trademark) supercomputer, all pointers are 64-bits long, and there is no native operation to fetch a smaller sized machine pointer. As another example, the significance and ordering of bytes in the pointer (xe2x80x9cendiannessxe2x80x9d) may vary from processor model to processor model.
One approach for addressing machine independence, known as xe2x80x9cpointer swizzling,xe2x80x9d employs two completely different formats for representing references: a machine-dependent runtime format using pointers for references in main memory, and a platform invariant format for encoding references in secondary storage. When the reference is written to secondary storage, machine pointers are converted into a machine-independent symbol such as a string or a serial number. When the reference is read back into main memory from secondary storage, the symbol is unswizzled and converted back into a machine pointer. Swizzling is also referred to as xe2x80x9cserializationxe2x80x9d and xe2x80x9cpickling.xe2x80x9d
The swizzling and the unswizzling operations, however, are computationally expensive, requiring many memory accesses into an auxiliary symbol table, typically implemented by a hash table or binary tree stored in memory. Thus, frequent storage and retrieval of program state into and out of secondary storage can be responsible for a significant drain on system performance. Therefore, a need exists for supporting an inexpensive platform-independent format for objects.
This need and others are addressed by one aspect of the present invention, in which objects residing in session memory are formatted so the references contained in the objects are in a machine-independent format, namely, that the references are encoded numerically. A exit table is provided to handle references with session memory that refer to locations in call memory, in which each entry in the exit table is associated with a corresponding reference in session memory and contains a pointer to the location in call memory. Thus, the exit table provides a convenient mechanism for identifying which objects in call memory are still alive because they are directly or indirectly referenced by session memory objects.
It is desirable to update the exit table efficiently. Another aspect of the invention is directed to maintaining an exit table, in which once an entry in the exit table is created for a particular reference in a memory space such as session memory, all further assignments to that reference are recorded in the exit table entry, even if the new value of the reference refers to a location that is inside the memory space.
Still other objects and advantages of the present invention will become readily apparent from the following detailed description, simply by way of illustration of the best mode contemplated of carrying out the invention. As will be realized, the invention is capable of other and different embodiments, and its several details are capable of modifications in various obvious respects, all without departing from the invention. Accordingly, the drawing and description are to be regarded as illustrative in nature, and not as restrictive.